"""
评价相关API - 集成WebSocket推送
"""
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from starlette.concurrency import run_in_threadpool
from typing import List, Optional

from utils.database import get_db
from utils import JWTUtils
from Models.travel.models import Review, Attraction, Order
from Models.login.models import User
from Views.home.websocket.ws_notifier import (
    notify_review_added,
    notify_review_replied
)
from pydantic import BaseModel, Field

router = APIRouter(prefix="/travel/reviews", tags=["评价管理"])


def get_current_user_id(request: Request) -> int:
    """从请求头获取当前用户ID"""
    authorization = request.headers.get("Authorization")
    if not authorization:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="未提供认证令牌"
        )
    
    token = authorization.replace("Bearer ", "").strip()
    payload = JWTUtils.decode_access_token(token)
    if not payload or not payload.get("user_id"):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="认证令牌无效"
        )
    return payload["user_id"]


class ReviewCreate(BaseModel):
    """创建评价请求"""
    attraction_id: int
    order_id: Optional[int] = None
    rating: float = Field(..., ge=0, le=5, description="评分（0-5）")
    content: Optional[str] = None
    images: Optional[str] = None  # JSON格式的图片列表


class ReviewInfo(BaseModel):
    """评价信息"""
    id: int
    user_id: int
    user_name: str = None
    attraction_id: int
    attraction_name: str = None
    order_id: Optional[int] = None
    rating: float
    content: Optional[str] = None
    images: Optional[str] = None
    is_visible: bool
    created_at: str
    updated_at: str
    
    class Config:
        from_attributes = True


class ReviewListResponse(BaseModel):
    """评价列表响应"""
    total: int
    page: int
    page_size: int
    reviews: List[ReviewInfo] = []


@router.post("", response_model=ReviewInfo, summary="创建评价")
async def create_review(
    review_data: ReviewCreate,
    request: Request,
    db: Session = Depends(get_db)
):
    """创建评价"""
    user_id = get_current_user_id(request)
    
    def _create_review():
        # 检查景点是否存在
        attraction = db.query(Attraction).filter(
            Attraction.id == review_data.attraction_id,
            Attraction.is_active == True
        ).first()
        
        if not attraction:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="景点不存在"
            )
        
        # 如果提供了订单ID，验证订单是否属于当前用户
        if review_data.order_id:
            order = db.query(Order).filter(
                Order.id == review_data.order_id,
                Order.user_id == user_id,
                Order.status == "completed"
            ).first()
            
            if not order:
                raise HTTPException(
                    status_code=status.HTTP_404_NOT_FOUND,
                    detail="订单不存在或未完成"
                )
        
        # 检查是否已评价过
        existing = db.query(Review).filter(
            Review.user_id == user_id,
            Review.attraction_id == review_data.attraction_id
        ).first()
        
        if existing:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="已评价过该景点"
            )
        
        # 创建评价
        review = Review(
            user_id=user_id,
            attraction_id=review_data.attraction_id,
            order_id=review_data.order_id,
            rating=review_data.rating,
            content=review_data.content,
            images=review_data.images
        )
        
        db.add(review)
        
        # 更新景点评分和评价数
        # 计算新的平均评分
        all_reviews = db.query(Review).filter(
            Review.attraction_id == review_data.attraction_id,
            Review.is_visible == True
        ).all()
        
        total_rating = sum(r.rating for r in all_reviews) + review_data.rating
        total_count = len(all_reviews) + 1
        new_rating = total_rating / total_count
        
        attraction.rating = new_rating
        attraction.review_count = total_count
        
        db.commit()
        db.refresh(review)
        
        return review, attraction
    
    review, attraction = await run_in_threadpool(_create_review)
    
    # 发送评价通知（这里可以通知管理员或景点所有者）
    # 注意：实际应用中可能需要根据业务逻辑决定通知谁
    notify_review_added(
        user_id=user_id,  # 这里可以改为管理员ID
        attraction_id=review_data.attraction_id,
        attraction_name=attraction.name,
        review_id=review.id,
        rating=review_data.rating
    )
    
    review_info = ReviewInfo.model_validate(review)
    review_info.attraction_name = attraction.name
    return review_info


@router.get("/attraction/{attraction_id}", response_model=ReviewListResponse, summary="获取景点评价列表")
async def get_attraction_reviews(
    attraction_id: int,
    page: int = 1,
    page_size: int = 10,
    db: Session = Depends(get_db)
):
    """获取指定景点的评价列表"""
    
    def _get_reviews():
        # 检查景点是否存在
        attraction = db.query(Attraction).filter(
            Attraction.id == attraction_id
        ).first()
        
        if not attraction:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="景点不存在"
            )
        
        query = db.query(Review).filter(
            Review.attraction_id == attraction_id,
            Review.is_visible == True
        )
        
        total = query.count()
        reviews = query.order_by(Review.created_at.desc()).offset(
            (page - 1) * page_size
        ).limit(page_size).all()
        
        # 加载用户信息
        for review in reviews:
            user = db.query(User).filter(User.id == review.user_id).first()
            if user:
                review.user_name = user.username
        
        return total, reviews, attraction.name
    
    total, reviews, attraction_name = await run_in_threadpool(_get_reviews)
    
    review_list = [ReviewInfo.model_validate(r) for r in reviews]
    for r in review_list:
        r.attraction_name = attraction_name
    
    return ReviewListResponse(
        total=total,
        page=page,
        page_size=page_size,
        reviews=review_list
    )


@router.get("/my", response_model=ReviewListResponse, summary="获取我的评价列表")
async def get_my_reviews(
    page: int = 1,
    page_size: int = 10,
    request: Request = None,
    db: Session = Depends(get_db)
):
    """获取当前用户的评价列表"""
    user_id = get_current_user_id(request)
    
    def _get_reviews():
        query = db.query(Review).filter(Review.user_id == user_id)
        
        total = query.count()
        reviews = query.order_by(Review.created_at.desc()).offset(
            (page - 1) * page_size
        ).limit(page_size).all()
        
        # 加载景点信息
        for review in reviews:
            if review.attraction:
                review.attraction_name = review.attraction.name
        
        return total, reviews
    
    total, reviews = await run_in_threadpool(_get_reviews)
    
    return ReviewListResponse(
        total=total,
        page=page,
        page_size=page_size,
        reviews=[ReviewInfo.model_validate(r) for r in reviews]
    )


@router.delete("/{review_id}", summary="删除评价")
async def delete_review(
    review_id: int,
    request: Request,
    db: Session = Depends(get_db)
):
    """删除评价（软删除，设置为不可见）"""
    user_id = get_current_user_id(request)
    
    def _delete_review():
        review = db.query(Review).filter(
            Review.id == review_id,
            Review.user_id == user_id
        ).first()
        
        if not review:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="评价不存在"
            )
        
        review.is_visible = False
        db.commit()
        
        return review
    
    review = await run_in_threadpool(_delete_review)
    return {"message": "评价已删除", "review_id": review_id}

